namespace Guia.Elements
{
    using System;
    using System.Windows.Automation;
    using Guia.Core;
    using Guia.Locator;

    /// <summary>
    /// This class represents a Slider. A Slider can be used to select a value.
    /// </summary>
    public class Slider : UiElement
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="Slider"/> class.
        /// </summary>
        /// <param name="automationElement">
        /// The automation element.
        /// </param>
        public Slider(AutomationElement automationElement)
            : base(automationElement)
        {
        }

        /// <summary>
        /// Gets the default-condition to find a control by its type.
        /// </summary>
        public static SearchCondition ControlTypeCondition
        {
            get { return SearchCondition.ByControlType(ControlType.Slider); }
        }

        /// <summary>
        /// Gets or sets the Value.
        /// </summary>
        /// <exception cref="OperationNotSupportedException">
        /// Throws an OperationNotSupportedException if the Slider is disabled or the value was out of range
        /// </exception>
        public double Value
        {
            get
            {
                return this.GetRangeValuePattern().Current.Value;
            }

            set
            {
                try
                {
                    this.GetRangeValuePattern().SetValue(value);
                }
                catch (ElementNotEnabledException)
                {
                    throw new OperationNotSupportedException("Element is not enabled");
                }
                catch (ArgumentOutOfRangeException)
                {
                    throw new OperationNotSupportedException("Value was out of range");
                }
            }
        }

        /// <summary>
        /// Gets the maximum possible value.
        /// </summary>
        public double Maximum
        {
            get
            {
                return this.GetRangeValuePattern().Current.Maximum;
            }
        }

        /// <summary>
        /// Gets the minimum possible value.
        /// </summary>
        public double Minimum
        {
            get
            {
                return this.GetRangeValuePattern().Current.Minimum;
            }
        }

        /// <summary>
        /// Gets the small-change value.
        /// </summary>
        public double SmallChange
        {
            get
            {
                return this.GetRangeValuePattern().Current.SmallChange;
            }
        }

        /// <summary>
        /// Gets the large-change value.
        /// </summary>
        public double LargeChange
        {
            get
            {
                return this.GetRangeValuePattern().Current.LargeChange;
            }
        }

        /// <summary>
        /// Increases the value by the value of SmallChange.
        /// </summary>
        public void SmallIncrease()
        {
            double newValue = this.GetRangeValuePattern().Current.Value + this.SmallChange;
            this.Value = newValue;
        }

        /// <summary>
        /// Decreases the value by the value of SmallChange.
        /// </summary>
        public void SmallDecrease()
        {
            double newValue = this.GetRangeValuePattern().Current.Value - this.SmallChange;
            this.Value = newValue;
        }

        /// <summary>
        /// Increases the value by the value of LargeChange.
        /// </summary>
        public void LargeIncrease()
        {
            double newValue = this.GetRangeValuePattern().Current.Value + this.LargeChange;
            this.Value = newValue;
        }

        /// <summary>
        /// Decreases the value by the value of LargeChange.
        /// </summary>
        public void LargeDecrease()
        {
            double newValue = this.GetRangeValuePattern().Current.Value - this.LargeChange;
            this.Value = newValue;
        }

        /// <summary>
        /// Returns the RangeValuePattern for this Slider.
        /// </summary>
        /// <returns>
        /// The RangeValuePattern.
        /// </returns>
        private RangeValuePattern GetRangeValuePattern()
        {
            return this.GetPattern<RangeValuePattern>();
        }
    }
}